﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace FishScore
{
    public partial class frmMain : Form
    {
        /// <summary>
        /// 主对象
        /// </summary>
        public FishGameObject game = null;

        /// <summary>
        /// 当前数据文件
        /// </summary>
        public string dataFile = null;

        /// <summary>
        /// 升降序标记
        /// </summary>
        public bool Descending = false;

        /// <summary>
        /// 所有钓手成绩分数列表
        /// </summary>
        public List<Score> scoreList;

        /// <summary>
        /// 程序所在目录包括斜杆
        /// </summary>
        public string dataPath;

        public frmMain()
        {
            InitializeComponent();
        }

        //获取目录下的json文件清单
        private string GetJsonFiles(string path)
        {
            string[] files = Directory.GetFiles(path, "*.json");

            if (files.Length == 1)////只有一个json文件就读取此数据
                return files[0];
            else//没有json数据文件或者多个文件
                return string.Empty;
        }

        /// <summary>
        /// 绑定List到DataGridView函数，解决Count=0绑定的情况下，更新数据出现鼠标点击界面出现-1异常
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dv"></param>
        /// <param name="list"></param>
        private void BindData<T>(DataGridView dv, List<T> list)
        {
            if ((list == null) || (dv == null)) return;

            if (list.Count > 0)
            {
                dv.DataSource = null;
                dv.DataSource = list;
            }
            else { dv.DataSource = null; }
        }

        //如果数据文件被修改或者数据不全时，创建默认列表数据对象
        private void InitGameList()
        {
            if (game == null) return;
            if (game.Matchs == null) game.Matchs = new List<Match>();
            if (game.Fishs == null) game.Fishs = new List<Fish>();
            if (game.Players == null) game.Players = new List<Player>();
            if (game.AddScores == null) game.AddScores = new List<AddScore>();
        }

        //切换到不同的tab，设置DataGridView列宽
        private void InitDataGridViewWidth(int tab)
        {
            switch (tab)
            {
                case 2:
                    dgViewFishes.Columns[0].Width = 60;//场次
                    dgViewFishes.Columns[1].Width = 60;//分区
                    dgViewFishes.Columns[2].Width = 60;//钓位
                    dgViewFishes.Columns[3].Width = 80;//报名号
                    dgViewFishes.Columns[4].Width = 100;//姓名
                    dgViewFishes.Columns[5].Width = 60;//尾数
                    dgViewFishes.Columns[6].Width = 60;//重量
                    dgViewFishes.Columns[7].Width = 60;//总分
                    break;
                case 3:
                    dgViewScores.Columns[0].Width = 80;//报名号
                    dgViewScores.Columns[1].Width = 100;//姓名
                    dgViewScores.Columns[2].Width = 80;//排名
                    dgViewScores.Columns[3].Width = 80;//总分
                    dgViewScores.Columns[4].Width = 100;//第1场成绩
                    dgViewScores.Columns[5].Width = 100;////第1场分数
                    dgViewScores.Columns[6].Width = 100;//第2场成绩
                    dgViewScores.Columns[7].Width = 100;//第2场分数
                    dgViewScores.Columns[8].Width = 100;//第3场成绩
                    dgViewScores.Columns[9].Width = 100;//第3场分数
                    dgViewScores.Columns[10].Width = 100;//第4场成绩
                    dgViewScores.Columns[11].Width = 100;//第4场分数
                    break;
                case 4:
                    dgViewTeamScores.Columns[0].Width = 180;//团队
                    dgViewTeamScores.Columns[1].Width = 60;//排名
                    dgViewTeamScores.Columns[2].Width = 60;//总分
                    dgViewTeamScores.Columns[3].Width = 100;//选手1姓名
                    dgViewTeamScores.Columns[4].Width = 100;//选手1分数
                    dgViewTeamScores.Columns[5].Width = 100;//选手2姓名
                    dgViewTeamScores.Columns[6].Width = 100;//选手2分数
                    dgViewTeamScores.Columns[7].Width = 100;//选手3姓名
                    dgViewTeamScores.Columns[8].Width = 100;//选手3分数
                    dgViewTeamScores.Columns[9].Width = 100;//选手4姓名
                    dgViewTeamScores.Columns[10].Width = 100;//选手4分数
                    break;
            }

        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            //提高DataGridView的响应速度
            DoubleBuffered(dgViewTeamScores);
            DoubleBuffered(dgViewFishes);
            DoubleBuffered(dgViewPlayers);
            DoubleBuffered(dgViewScores);

            dataPath = Path.GetDirectoryName(Application.ExecutablePath) + "\\";

            string json = GetJsonFiles(dataPath);

            if (json == string.Empty)
            {
                game = new FishGameObject();
                game.InitEmptyObject();
                dataFile = dataPath + game.GameName + ".json";
            }
            else if (File.Exists(json))
            {
                game = DataFile.LoadDataFile(json);
                InitGameList();
                dataFile = json;
            }

            ShowGameInfo(game);
            //初始化各类选择框和下拉框
            InitUIList();
        }

        private void btnOpenGame_Click(object sender, EventArgs e)
        {
            dlgOpen.InitialDirectory = dataPath;
            if (dlgOpen.ShowDialog() == DialogResult.OK)
            {
                dataFile = dlgOpen.FileName;
                game = DataFile.LoadDataFile(dataFile);

                InitGameList();

                game.GameName = Path.GetFileNameWithoutExtension(dataFile);
                dataPath = Path.GetDirectoryName(dataFile) + "\\";
                ShowGameInfo(game);

                //初始化各类选择框和下拉框
                InitUIList();
            }
        }

        private void EnableGameInfo(bool enable)
        {
            dtDate.Enabled = enable;
            numAreaCount.Enabled = enable;
            numAreaPlayers.Enabled = enable;
            numStartPos.Enabled = enable;
            numSeprate.Enabled = enable;
            txtGameName.Enabled = enable;
        }

        //动态更新违规加分信息
        private void ShowAddScoreInfo()
        {
            if (game == null) return;

            txtAddScore.Clear();
            foreach (var score in game.AddScores)
            {
                txtAddScore.AppendText(score.ToString() + "\r\n");
            }
        }

        private void ShowGameInfo(FishGameObject obj)
        {
            txtGameName.Text = obj.GameName;
            numAreaCount.Value = obj.AreaCount;
            numAreaPlayers.Value = obj.AreaPlayers;
            dtDate.Value = DateTime.Parse(obj.Date);
            numStartPos.Value = obj.AreaStartPos;
            numSeprate.Value = obj.SeprateNumber;

            BindData<Player>(dgViewPlayers, obj.Players);
            BindData<Fish>(dgViewFishes, obj.Fishs);
        }

        private void UpdateGameInfo(ref FishGameObject obj)
        {
            if (obj == null)
            {
                obj = new FishGameObject();
                obj.InitEmptyObject();
                dataFile = dataPath + obj.GameName + ".json";
            }
            obj.GameName = txtGameName.Text;
            obj.AreaCount = (int)numAreaCount.Value;
            obj.Date = dtDate.Value.ToString("D");
            obj.SeprateNumber = (int)numSeprate.Value;
            obj.AreaPlayers = (int)numAreaPlayers.Value;

            if (true)
            {
                obj.AreaStartPos = (int)numStartPos.Value;
                obj.AreaPlayers = (int)numAreaPlayers.Value;
                obj.SeprateNumber = (int)numSeprate.Value;
                obj.Matchs.ForEach(x => x.StartPos = (int)numStartPos.Value);
                obj.Matchs.ForEach(x => x.SeprateNumber = (int)numSeprate.Value);
                obj.Matchs.ForEach(x => x.EndPos = x.StartPos + ((int)numAreaPlayers.Value * ((int)numSeprate.Value + 1)) - 1);
            }

            //如果修改了比赛名称，删除老数据文件
            if (Path.GetFileNameWithoutExtension(dataFile) != obj.GameName)
            {
                File.Delete(dataFile);
            }
            dataFile = dataPath + txtGameName.Text + ".json";
        }

        private void btnNewOrModify_Click(object sender, EventArgs e)
        {
            btnInfoSave.Enabled = true;
            EnableGameInfo(true);
        }

        private void btnInfoSave_Click(object sender, EventArgs e)
        {
            UpdateGameInfo(ref game);
            EnableGameInfo(false);
            btnInfoSave.Enabled = false;
            DataFile.SaveDataFile(game, dataFile);
            ///修改比赛基础信息后，重新初始化下拉列表
            InitUIList();
        }

        private void btnImportPlayers_Click(object sender, EventArgs e)
        {
            string[] players = null;
            frmImportPlayers frm = new frmImportPlayers();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                players = frm.playerInfo;

                if (frm.clearOlder)
                    game.Players.Clear();

                ImportPlayers(game, players);
                BindData<Player>(dgViewPlayers, game.Players);
            }
        }

        // 以下为同步修改后的关键片段，已将所有Data.cs对象属性访问统一为PascalCase风格

        private void ImportPlayers(FishGameObject obj, string[] playerInfos)
        {
            if (playerInfos.Length == 0) return;

            foreach (string playerInfo in playerInfos)
            {
                string[] info = playerInfo.Replace("\"", "").Trim().Split(',');

                if (info.Length < 2) continue;

                Player player = new Player();
                player.ID = Int32.Parse(info[0]);
                player.Name = info[1];
                player.Phone = info.Length > 2 ? info[2] : "无";
                player.Team = info.Length > 3 ? info[3] : "无";
                obj.Players.Add(player);
            }

            DataFile.SaveDataFile(game, dataFile);
        }

        private void dgViewPlayers_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            DataFile.SaveDataFile(game, dataFile);
        }

        private void InitUIList()
        {
            InitAreaInfo();
            InitMatchInfo();
        }

        private void InitAreaInfo()
        {
            cbArea.Items.Clear();
            for (int i = 0; i < game.AreaCount; i++)
            {
                cbArea.Items.Add((i + 1).ToString() + "区");
            }

            cbArea.SelectedIndex = 0;
        }

        private void InitMatchInfo()
        {
            cbMatch.Items.Clear();
            for (int i = 0; i < 4; i++)
            {
                cbMatch.Items.Add("第" + (i + 1).ToString() + "场");
            }
            cbMatch.SelectedIndex = 0;
        }

        private void txtPlayerID_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                btnAddResult.PerformClick();
            }

            if (!char.IsDigit(e.KeyChar) && (e.KeyChar != '.') && (e.KeyChar != (char)8))
            {
                e.Handled = true;
            }
        }

        private void btnAddResult_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtPlayerID.Text)) return;
            if (cbArea.SelectedItem == null) return;
            if (cbMatch.SelectedItem == null) return;   

            int areaId = Int32.Parse((cbArea.SelectedItem as string).Substring(0, 1));
            int matchId = Int32.Parse((cbMatch.SelectedItem as string).Substring(1, 1));
            int playerId = Int32.Parse(txtPlayerID.Text);

            Player player = game.GetPlayerByID(playerId);
            if (player == null)
            {
                MessageBox.Show("找不到此报名号的钓手");
                return;
            }

            Fish fishOld = game.GetFishByMatchAndPlayer(matchId, playerId);

            if (fishOld != null)
            {
                MessageBox.Show($"{player.Name} 成绩已录入：第{fishOld.MatchId}场{fishOld.AreaId}区{fishOld.AreaPos}号");
                return;
            }

            frmAddResult frm = new frmAddResult();
            frm.areaId = areaId;
            frm.matchId = matchId;
            frm.playerId = playerId;
            frm.game = game;
            frm.UpdateUI();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                if (game.GetFishByMatchAndAreaAndPos(frm.matchId, frm.areaId, frm.areaPos) != null)
                {
                    MessageBox.Show("此位置已有其他人录入了成绩");
                    return;
                }

                if (frm.value == -1)
                    return;

                Fish fish = new Fish();
                fish.MatchId = frm.matchId;
                fish.AreaId = frm.areaId;
                fish.AreaPos = frm.areaPos;
                fish.PlayerId = frm.playerId;
                if (fish.AreaId > 4)
                    fish.Count = (int)frm.value;
                else
                    fish.Weight = frm.value;
                game.Fishs.Add(fish);
                DataFile.SaveDataFile(game, dataFile);

                FilterFish();
            }

            txtPlayerID.Focus();
            txtPlayerID.Text = string.Empty;
        }

        private void btnSaveFish_Click(object sender, EventArgs e)
        {
            ShowAddScoreInfo();
            gbaddscore.Visible = true;
        }

        private void dgViewResults_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            if (e.RowIndex < 0) return;

            DataGridView dv = sender as DataGridView;
            if (dv == null) return;

            if (dv.Columns[e.ColumnIndex].HeaderText == "姓名")
            {
                e.Value = game.GetPlayerByID((dv.DataSource as List<Fish>)[e.RowIndex].PlayerId).Name;
            }

            if (dv.Columns[e.ColumnIndex].HeaderText == "团队")
            {
                e.Value = game.GetPlayerByID((dv.DataSource as List<Fish>)[e.RowIndex].PlayerId).Team;
            }
        }

        private void FilterFish()
        {
            string smatch = (cbMatch.SelectedItem as string);
            if (string.IsNullOrEmpty(smatch)) return;
            smatch = smatch.Substring(1, 1);

            string sarea = (cbArea.SelectedItem as string);
            if (string.IsNullOrEmpty(sarea)) return;
            sarea = sarea.Substring(0, 1);

            Int32.TryParse(smatch, out int mid);
            Int32.TryParse(sarea, out int aid);

            List<Fish> list = game.GetFishByMatchAndArea(mid, aid);

            BindData<Fish>(dgViewFishes, list);
        }

        private void cbArea_SelectedIndexChanged(object sender, EventArgs e)
        {
            FilterFish();
        }

        private void cbMatch_SelectedIndexChanged(object sender, EventArgs e)
        {
            FilterFish();
        }

        private void btnImportFish_Click(object sender, EventArgs e)
        {
            frmImportPlayers frm = new frmImportPlayers();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                if (frm.clearOlder)
                    game.Fishs.Clear();
                ImportFishes(game, frm.playerInfo);
                FilterFish();
            }
        }

        private void ImportFishes(FishGameObject obj, string[] fishes)
        {
            if (fishes.Length == 0) return;

            foreach (string fishInfo in fishes)
            {
                string[] info = fishInfo.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

                if (info.Length < 5) continue;

                Fish fish = new Fish();
                fish.MatchId = Int32.Parse(info[0]);
                fish.AreaId = Int32.Parse(info[1]);
                fish.AreaPos = Int32.Parse(info[2]);
                fish.PlayerId = Int32.Parse(info[3]);
                if (Int32.Parse(info[1]) > 4)
                    fish.Count = Int32.Parse(info[4]);
                else
                    fish.Weight = float.Parse(info[4]);

                game.Fishs.Add(fish);
            }
            DataFile.SaveDataFile(game, dataFile);
        }

        private void dgViewFishes_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            List<Fish> list = (dgViewFishes.DataSource as List<Fish>);

            switch (e.ColumnIndex)
            {
                case 0:
                case 1:
                case 4:
                    break;

                case 2://根据钓位号排序
                    if (Descending)
                        list = list.OrderBy(x => x.AreaPos).ToList();
                    else
                        list = list.OrderByDescending(x => x.AreaPos).ToList();
                    break;

                case 3://根据报名号排序
                    if (Descending)
                        list = list.OrderBy(x => x.PlayerId).ToList();
                    else
                        list = list.OrderByDescending(x => x.PlayerId).ToList();
                    break;

                case 5://根据尾数排序
                    if (Descending)
                        list = list.OrderBy(x => x.Count).ToList();
                    else
                        list = list.OrderByDescending(x => x.Count).ToList();
                    break;

                case 6://根据重量排序
                    if (Descending)
                        list = list.OrderBy(x => x.Weight).ToList();
                    else
                        list = list.OrderByDescending(x => x.Weight).ToList();
                    break;

                case 7://根据分区分数排序
                    if (Descending)
                        list = list.OrderBy(x => x.AreaScore).ToList();
                    else
                        list = list.OrderByDescending(x => x.AreaScore).ToList();
                    break;
            }

            Descending = !Descending;

            if (list == null) return;

            BindData<Fish>(dgViewFishes, list);
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControl1.SelectedIndex == 2)
            {
                txtPlayerID.Text = string.Empty;
                txtPlayerID.Focus();

                FilterFish();

            }
            InitDataGridViewWidth(tabControl1.SelectedIndex);
        }

        private void btnQuery_Click(object sender, EventArgs e)
        {
            if (txtPlayerID.Text.Length == 0) return;

            BindData<Fish>(dgViewFishes, game?.GetFishByPlayerId(Int32.Parse(txtPlayerID.Text)));
        }

        private void dgViewFishes_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
        {
            e.Row.HeaderCell.Value = string.Format("{0}", e.Row.Index + 1);
        }

        private void btnArea_Click(object sender, EventArgs e)
        {
            string smatch = (cbMatch.SelectedItem as string);
            if (string.IsNullOrEmpty(smatch)) return;
            smatch = smatch.Substring(1, 1);
            int mid = Int32.Parse(smatch);

            List<Fish> list = game.GetFishByMatch(mid);

            BindData<Fish>(dgViewFishes, list);
        }

        private void btnAllMatch_Click(object sender, EventArgs e)
        {
            BindData<Fish>(dgViewFishes, game.Fishs);
        }

        private void dgViewFishes_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F2)
                dgViewFishes.BeginEdit(true);
        }

        private void btnExportFish_Click(object sender, EventArgs e)
        {
            if (dgViewFishes.Rows.Count == 0) return;

            DataFile.TableSave(dgViewFishes);
        }

        private void btnCalcScore_Click(object sender, EventArgs e)
        {
            CalculateAreaScore(dgViewFishes.DataSource as List<Fish>);
            List<Fish> list = (dgViewFishes.DataSource as List<Fish>);

            BindData<Fish>(dgViewFishes, list);

            DataFile.SaveDataFile(game, dataFile);
        }

        //计算分区成绩分数
        private void CalculateAreaScore(List<Fish> list)
        {
            if (list == null) return;

            if (list.Count == 0) return;

            var sortList = list;
            float[] values;

            float curValue;

            int index = 0;

            if (list[0].AreaId < 5)
            {
                //获取混养鱼重量排序数组
                sortList = list.OrderByDescending(x => x.Weight).ToList();
                values = sortList.Select(x => x.Weight).ToArray();
            }
            else
            {
                //获取对象鱼数量排序数组
                sortList = list.OrderByDescending(x => x.Count).ToList();
                values = sortList.Select(x => (float)x.Count).ToArray();
            }

            for (int j = 0; j < values.Length; j++)
            {
                curValue = values[j];

                //成绩0，分数为钓位数
                if (curValue == 0)
                {
                    Match mat = game.GetMatchById(sortList[j].MatchId);
                    if (mat != null)
                    {
                        sortList[j].AreaScore = mat.EndPos - mat.StartPos + 1;
                    }
                    continue;
                }

                //获取成绩相同个数
                int count = GetSameCount(curValue, values);

                index++;

                //没有相同成绩按位次给分数
                if (count == 1)
                {
                    sortList[j].AreaScore = index;
                    continue;
                }

                //计算相同成绩的分数
                int sum = 0;
                for (int i = 0; i < count; i++)
                {
                    sum = sum + index + i;
                }

                //相同成绩的每个人都赋相同分
                for (int k = 0; k < count; k++)
                {
                    sortList[j + k].AreaScore = (float)Math.Round((double)sum / count, 1);
                }
                //跳过相同的个数
                j = j + count - 1;
                index = index + count - 1;
            }
        }

        private int GetSameCount(float value, float[] arr)
        {
            return arr.Count(n => n == value);
        }

        private void dgViewPlayers_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F2)
                dgViewPlayers.BeginEdit(true);
        }

        private void btnCal_Click(object sender, EventArgs e)
        {
            InitTwoMatchUI(true);
            AddTwoMatchColumn(false);
            scoreList = game.InitScore();
            game.CalculateScores(ref scoreList, chkNotALL.Checked);

            BindData<Score>(dgViewScores, scoreList);
        }

        private void btnExportScores_Click(object sender, EventArgs e)
        {
            if (dgViewScores.RowCount == 0)
                return;

            ExportHelper.ExportDetails(
                DataFile.GetDataTable(dgViewScores), ExportHelper.ExportFormat.CSV,
                dataPath + game.GameName + "个人排名.csv", ExportHelper.ApplicationType.WindowsForm);

            MessageBox.Show("导出成功");
        }

        public float GetTotalScoreByPlayerID(int playerID)
        {
            Score score = scoreList.Where(x => x.PlayerId == playerID).FirstOrDefault();
            if (score == null) return game.AreaPlayers * 4;//未参加全部场次的人员，直接返回满分

            return score.TotalScore;
        }

        /// <summary>
        /// 判断一个团队的人员是否齐全，每个队员的成绩是否齐全
        /// </summary>
        /// <param name="team"></param>
        /// <returns></returns>
        public bool IsEmptyTeam(TeamRank team)
        {
            string name = team.TeamName;

            List<Player> playList = game.Players.Where(x => x.Team == name).ToList();

            if (playList.Count != 4) return true;

            foreach (Player player in playList)
            {
                if (game.Fishs.Count(x => x.PlayerId == player.ID) != 4) return true;
            }

            return false;
        }

        /// <summary>
        /// 统计团队成绩
        /// </summary>
        /// <param name="list"></param>
        public void CalculateTeamScore(List<TeamRank> list)
        {
            if (list == null) return;

            if (scoreList == null) return;

            foreach (var item in list)
            {
                List<Player> players = game.Players.Where(x => x.Team == item.TeamName).ToList();

                //团队每个人默认直接赋满分
                item.Play1Score = (float)game.AreaPlayers * 4;
                item.Play2Score = (float)game.AreaPlayers * 4;
                item.Play3Score = (float)game.AreaPlayers * 4;
                item.Play4Score = (float)game.AreaPlayers * 4;

                if (players.Count > 0)
                {
                    item.Play1Name = players[0].Name;
                    item.Play1Score = GetTotalScoreByPlayerID(players[0].ID);
                }

                if (players.Count > 1)
                {
                    item.Play2Name = players[1].Name;
                    item.Play2Score = GetTotalScoreByPlayerID(players[1].ID);
                }
                if (players.Count > 2)
                {
                    item.Play3Name = players[2].Name;
                    item.Play3Score = GetTotalScoreByPlayerID(players[2].ID);
                }

                if (players.Count > 3)
                {
                    item.Play4Name = players[3].Name;
                    item.Play4Score = GetTotalScoreByPlayerID(players[3].ID);
                }

                item.TeamScore = item.Play1Score + item.Play2Score + item.Play3Score + item.Play4Score;
            }

            if (chkTeamNotAll.Checked)
                list.RemoveAll(x => (IsEmptyTeam(x)));

            list.Sort(new TeamScoreCompare());
        }

        private void btnCalTeam_Click(object sender, EventArgs e)
        {
            List<TeamRank> teamList = game.InitTeam();
            CalculateTeamScore(teamList);
            //更新排名字段
            for (int i = 0; i < teamList.Count; i++)
            {
                teamList[i].Rank = i + 1;
            }

            BindData<TeamRank>(dgViewTeamScores, teamList);
        }

        private void btnExportTeam_Click(object sender, EventArgs e)
        {
            if (dgViewTeamScores.RowCount == 0)
                return;

            ExportHelper.ExportDetails(
                DataFile.GetDataTable(dgViewTeamScores), ExportHelper.ExportFormat.CSV,
                dataPath + game.GameName + "团体排名.csv", ExportHelper.ApplicationType.WindowsForm);

            MessageBox.Show("导出成功");
        }

        private void btnExportPlayers_Click(object sender, EventArgs e)
        {
            if (dgViewPlayers.RowCount == 0)
                return;

            ExportHelper.ExportDetails(
                DataFile.GetDataTable(dgViewPlayers), ExportHelper.ExportFormat.CSV,
                dataPath + game.GameName + "选手信息表.csv", ExportHelper.ApplicationType.WindowsForm);

            MessageBox.Show("导出成功");
        }

        /// <summary>
        /// 开启DataGridView控件的双缓冲属性，提高控件界面响应速度
        /// </summary>
        /// <param name="dgvMain"></param>
        public static void DoubleBuffered(System.Windows.Forms.DataGridView dgvMain)
        {
            Type type = dgvMain.GetType();
            System.Reflection.PropertyInfo pi = type.GetProperty("DoubleBuffered",
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            pi.SetValue(dgvMain, true, null);
        }

        /// <summary>
        /// 未录入成绩人员
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmnNoScorePlayer_Click(object sender, EventArgs e)
        {
            string smatch = (cbMatch.SelectedItem as string);
            if (string.IsNullOrEmpty(smatch)) return;
            smatch = smatch.Substring(1, 1);

            List<Player> players = game.Players.Where(player => game.Fishs.Where(fish => fish.MatchId == Int32.Parse(smatch)).Where(fish2 => fish2.PlayerId == player.ID).Count() == 0).ToList();

            ShowNoFishPlayers(players);
        }

        private void ShowNoFishPlayers(List<Player> players)
        {
            if (players == null) return;
            string playInfo = $"目前有{players.Count()}人未录入成绩，名单如下：\r\n\r\n\r\n";
            foreach (Player player in players)
            {
                playInfo += $"报名号：{player.ID:D3}\t姓名：{player.Name}\t电话:{player.Phone}\t团队:{player.Team}\r\n";
            }

            MessageBox.Show(playInfo);
        }

        private void InitTwoMatchUI(bool visible)
        {
            dgViewScores.Columns[8].Visible = visible;
            dgViewScores.Columns[9].Visible = visible;
            dgViewScores.Columns[10].Visible = visible;
            dgViewScores.Columns[11].Visible = visible;
            //dgViewScores.Columns["scoreTeamName"].Visible = visible;
        }

        private void AddTwoMatchColumn(bool add)
        {
            return;

            DataGridViewTextBoxColumn col;
            if (add)
            {
                if (dgViewScores.Columns.Count >= 15)
                    return;

                col = new DataGridViewTextBoxColumn();
                col.HeaderText = "第1场区号";
                col.DataPropertyName = "areaId1";
                col.Name = "areaId1";
                dgViewScores.Columns.Add(col);
                col = new DataGridViewTextBoxColumn();
                col.HeaderText = "第2场区号";
                col.DataPropertyName = "areaId2";
                col.Name = "areaId2";
                dgViewScores.Columns.Add(col);
            }
            else
            {
                col = dgViewScores.Columns["areaId1"] as DataGridViewTextBoxColumn;
                if (col != null)
                {
                    dgViewScores.Columns.Remove(col);
                }
                col = dgViewScores.Columns["areaId2"] as DataGridViewTextBoxColumn;
                if (col != null)
                {
                    dgViewScores.Columns.Remove(col);
                }
            }
        }

        private void btnTwoMatch_Click(object sender, EventArgs e)
        {
            InitTwoMatchUI(false);
            AddTwoMatchColumn(true);

            scoreList = game.InitScore();
            game.CalculateScores2(ref scoreList, false);

            BindData<Score>(dgViewScores, scoreList);
        }

        private void dgViewFishes_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            DataFile.SaveDataFile(game, dataFile);
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            UpdateAddScores();
            gbaddscore.Visible = false;
        }

        private void UpdateAddScores()
        {
            List<string> list = new List<string>();

            foreach (var score in txtAddScore.Lines)
            {
                if (string.IsNullOrEmpty(score)) continue;

                string scoreText = score.Replace("，", ",");//替换中文逗号

                string[] info = scoreText.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                if (info.Length == 3)
                    list.Add(scoreText);
            }

            if (game == null) return;

            if (list.Count == game.AddScores.Count) return;//没有修改

            game.AddScores.Clear();

            foreach (var score in list)
            {
                string[] info = score.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                if (info.Length != 3) continue;

                int playerID = Int32.Parse(info[0]);
                int matchId = Int32.Parse(info[1]);
                int addScore = Int32.Parse(info[2]);
                game.AddScores.Add(new AddScore() { PlayerId = playerID, MatchId = matchId, Score = addScore });
            }

            DataFile.SaveDataFile(game, dataFile);

            //测试Git恢复功能
        }
    }
}